package com.i4season.camera;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.os.Environment;
import android.util.Log;

import com.alibaba.fastjson.JSONObject;
import com.example.i4seasoncameralib.cameramanager.CameraManager;
import com.example.i4seasoncameralib.cameramanager.handler.CameraConstant;
import com.example.i4seasoncameralib.cameramanager.handler.CameraEventObserver;
import com.jni.logmanageOtg.LogManagerWD;

import java.util.HashMap;
import java.util.Map;

import io.dcloud.common.core.permission.PermissionControler;
import io.dcloud.feature.uniapp.annotation.UniJSMethod;
import io.dcloud.feature.uniapp.bridge.UniJSCallback;
import io.dcloud.feature.uniapp.common.UniModule;

public class OtgCameraModule extends UniModule {
    private static final String TAG = "OtgCameraTool";

    /**
     * 相机事件
     */
    private static final String EVENT_CAMERA = "cameraEvent";
    /**
     * 媒体(Photo/Video)事件
     */
    private static final String EVENT_MEDIA = "mediaEvent";
    private static final String EVENT_BITMAP = "bitmapEvent";

    final int PERMISSION_CODE = 11111;
    private static final String[] permissions = new String[]{
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_EXTERNAL_STORAGE
    };

    /**
     * 申请权限
     */
    @UniJSMethod(uiThread = true)
    public void requestPermissions() {
        Context context = mUniSDKInstance.getContext();
        if (null != context) {
            Activity activity = (Activity) context;
            PermissionControler.requestPermissions(activity, permissions, PERMISSION_CODE);
        }
    }

    /**
     * 申请权限
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        if (requestCode == PERMISSION_CODE) {
            for (int i = 0; i < permissions.length; i++) {
                String preName = permissions[i];
                int granted = grantResults[i];
                if (Manifest.permission.READ_EXTERNAL_STORAGE.equals(preName) && granted == PackageManager.PERMISSION_GRANTED) {
                    //获取权限结果-TODO

                }
            }
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    @UniJSMethod(uiThread = true)
    public void initCamera(UniJSCallback callback) {
        Context context = mUniSDKInstance.getContext();
        try {
            CameraConstant.SAVE_SELF = false;
            CameraConstant.SAVE_CIRCLE = false;
            CameraConstant.app_album_name = "/OTGCamearSDKDemo";
            String absolutePath = context.getApplicationContext()
                    .getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath();
            LogManagerWD.APP_SDCARD = absolutePath;

            CameraManager.getInstance().initProgrammeSdk(context.getApplicationContext());

            CameraManager.getInstance().checkOtgCamera(context);
            CameraManager.getInstance().setOnOfflineListener(new CameraEventObserver.OfflineListener() {
                @Override
                public void onOnlineListener() {
                    sendCameraEvent(cameraParams(true, "ONLINE"));
                    if (null != callback) {
                        JSONObject data = new JSONObject();
                        data.put("deviceOnline", true);
                        callback.invoke(data);
                    }
                }

                @Override
                public void onOfflineListener() {
                    if (null != callback) {
                        JSONObject data = new JSONObject();
                        data.put("deviceOnline", false);
                        callback.invoke(data);
                    }
                    sendCameraEvent(cameraParams(false, "OFFLINE"));
                }

                @Override
                public void onConnectingListener() {
                    if (null != callback) {
                        JSONObject data = new JSONObject();
                        data.put("deviceState", "CONNECTING");
                        callback.invoke(data);
                    }
                    sendCameraEvent(cameraParams(false, "CONNECTING"));
                }

                @Override
                public void onConnectErrorListener(int i) {
                    if (null != callback) {
                        JSONObject data = new JSONObject();
                        data.put("deviceState", "ERROR:" + i);
                        callback.invoke(data);
                    }
                    sendCameraEvent(cameraParams(false, "ERROR:" + i));
                }

                @Override
                public void onUpdataDeviceListener() {
                    if (null != callback) {
                        JSONObject data = new JSONObject();
                        data.put("deviceState", "UPDATE");
                        callback.invoke(data);
                    }
                    sendCameraEvent(cameraParams(true, "UPDATE"));
                }
            });
            int deviceOnlineStatus = CameraManager.getInstance().getDeviceOnlineStatus();

            CameraManager.getInstance().setOnAcceptBitmapListener(bitmap -> {
                if (null != callback) {
                    JSONObject data = new JSONObject();
                    data.put("AcceptBitmap", bitmap);
                    callback.invoke(data);
                }
                sendEvent(EVENT_BITMAP, bitmapParams(bitmap));

            }, false);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 拍照
     */
    @UniJSMethod(uiThread = true)
    public void takePhoto(Bitmap bitmap, UniJSCallback callback) {
        if (null != bitmap)
            CameraManager.getInstance().takePhoto(bitmap, (success, path, type) -> {
                if (null != callback) {
                    JSONObject data = new JSONObject();
                    data.put("takePhoto", String.valueOf(success));
                    data.put("photoPath", path);
                    data.put("type", type);
                    callback.invoke(data);
                }
                sendMediaEvent(mediaParams(success, path, type));
            });
    }

    /**
     * 开始录像
     */
    @UniJSMethod(uiThread = true)
    public void startRecord(UniJSCallback callback) {
        CameraManager.getInstance().startVideoRecoder();
        if (null != callback) {
            JSONObject data = new JSONObject();
            data.put("recordStarted", true);
            callback.invoke(data);
        }
    }

    /**
     * 结束录像
     */
    @UniJSMethod(uiThread = true)
    public void stopRecord(UniJSCallback callback) {
        CameraManager.getInstance().stopVideoRecoder((success, path, type) -> {
            if (null != callback) {
                JSONObject data = new JSONObject();
                data.put("takeVideo", String.valueOf(success));
                data.put("videoPath", path);
                data.put("type", type);
                callback.invoke(data);
            }
            sendMediaEvent(mediaParams(success, path, type));
        });
    }

    /**
     * @param online Camera是否在线
     * @param state  Camera状态
     */
    private Map<String, Object> cameraParams(boolean online, String state) {
        Map<String, Object> params = new HashMap<>();
        params.put("online", online);
        params.put("state", state);

        return params;
    }

    /***/
    private void sendCameraEvent(Map<String, Object> params) {
        sendEvent(EVENT_CAMERA, params);
    }

    /***/
    private void sendMediaEvent(Map<String, Object> params) {
        sendEvent(EVENT_MEDIA, params);
    }

    /**
     * <a href="https://nativesupport.dcloud.net.cn/NativePlugin/course/android.html#globalevent-%E4%BA%8B%E4%BB%B6">globalEvent 事件</a>
     */
    private void sendEvent(String eventName, Map<String, Object> params) {
        mUniSDKInstance.fireGlobalEventCallback(eventName, params);
    }

    /**
     * @param successful 操作是否成功
     * @param path       存储路径
     * @param type       拍照和视频结束:3,
     */
    private Map<String, Object> mediaParams(boolean successful, String path, int type) {
        Map<String, Object> params = new HashMap<>();
        params.put("successful", successful);
        params.put("path", path);
        params.put("type", type);

        return params;
    }

    private Map<String, Object> bitmapParams(Bitmap bitmap) {
        Map<String, Object> params = new HashMap<>();
        params.put("acceptBitmap", bitmap);

        return params;
    }


    /**
     * --------------------------------------------------------
     */
    public static int REQUEST_CODE = 1000;

    //run ui thread
    @UniJSMethod(uiThread = true)
    public void testAsyncFunc(JSONObject options, UniJSCallback callback) {
        Log.e(TAG, "testAsyncFunc--" + options);
        if (callback != null) {
            JSONObject data = new JSONObject();
            data.put("code", "success");
            callback.invoke(data);
            //callback.invokeAndKeepAlive(data);
        }
    }

    //run JS thread
    @UniJSMethod(uiThread = false)
    public JSONObject testSyncFunc() {
        JSONObject data = new JSONObject();
        data.put("code", "success");
        return data;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_CODE && data.hasExtra("respond")) {
            Log.e("TestModule", "原生页面返回----" + data.getStringExtra("respond"));
        } else {
            super.onActivityResult(requestCode, resultCode, data);
        }
    }

    @UniJSMethod(uiThread = true)
    public void gotoOtgCameraPage() {
        try {
            if (mUniSDKInstance != null && mUniSDKInstance.getContext() instanceof Activity) {
                Intent intent = new Intent(mUniSDKInstance.getContext(), NativeOtgCameraActivity.class);
                ((Activity) mUniSDKInstance.getContext()).startActivityForResult(intent, REQUEST_CODE);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @UniJSMethod(uiThread = true)
    public void gotoTestPage() {
        try {
            Context context = null == mUniSDKInstance ? null : mUniSDKInstance.getContext();
            if (context instanceof Activity) {
                Intent intent = new Intent(context, NativeTestActivity.class);
                context.startActivity(intent);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
